import re
from dataclasses import dataclass
from typing import Optional

from model.security_risk import SecurityRisk


@dataclass
class Vulnerability:
    """
    unique identifier for the vulnerability (e.g., rust: https://rustsec.org/advisories/RUSTSEC-2020-0159,
    npm: https://github.com/advisories/GHSA-4wf5-vphf-c2xc)
    """

    id: str
    """short name for the vulnerability (e.g., rust: RUSTSEC-2020-0159, npm: GHSA-4wf5-vphf-c2xc)"""
    name: str
    """
    short description of the vulnerability (e.g., rust: Potential segfault in localtime_r invocations,
    npm: Terser insecure use of regular expressions before v4.8.1 and v5.14.2 leads to ReDoS)
    """
    description: str
    """score of the vulnerability or -1 if no score could be determined"""
    score: int = -1
    """note for risk assessment, first word is trying to be parsed as SecurityRisk, might be empty"""
    risk_note: str = " "

    def __post_init__(self):
        """Validate field values after initialization"""
        assert self.id is not None and len(self.id) > 0
        assert self.name is not None and len(self.name) > 0
        assert self.description is not None and len(self.description) > 0
        assert self.score >= -1
        assert self.risk_note is not None

    def get_risk(self) -> Optional[SecurityRisk]:
        match = re.match(r"\s*(?P<first_word>[a-z]+)", self.risk_note, re.IGNORECASE)
        return SecurityRisk.of(match.group("first_word")) if match else None

    def has_risk_note(self):
        return re.match(r"\s*\S", self.risk_note)
